<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>canvas粒子动画</title>

    <style>
        #canvas {

            position: absolute;

            display: block;

            left: 0;

            top: 0;

            background: #0f0f0f;

            z-index: -1;

        }
    </style>

</head>

<body>

    <canvas id="canvas"></canvas>

    <script>
        var canvas = document.getElementById("canvas");

        var ctx = canvas.getContext("2d");

        var opt = {

            particleAmount: 50, //粒子个数

            defaultSpeed: 1, //粒子运动速度

            variantSpeed: 1, //粒子运动速度的变量

            particleColor: "rgb(32,245,245)", //粒子的颜色

            lineColor: "rgb(32,245,245)", //网格连线的颜色

            defaultRadius: 2, //粒子半径

            variantRadius: 2, //粒子半径的变量

            minDistance: 200 //粒子之间连线的最小距离

        };

        var line = opt.lineColor.match(/\d+/g);

        console.log(line);

        var particle = [],
            w, h;

        var delay = 200,
            tid;

        init();

        window.addEventListener("resize", function () {

            winResize()

        }, false);



        function winResize() {

            clearTimeout(tid);

            tid = setTimeout(function () {

                getSize();

            }, delay)

        }



        function init() {

            getSize();

            for (let i = 0; i < opt.particleAmount; i++) {

                particle.push(new Partical());

            }

            loop();

        }



        function loop() {

            ctx.clearRect(0, 0, w, h);

            for (let i = 0; i < particle.length; i++) {

                particle[i].update();

                particle[i].draw();

            }

            for (let i = 0; i < particle.length; i++) {

                linePoint(particle[i], particle)

            }

            window.requestAnimationFrame(loop);

        }



        function linePoint(point, hub) {

            for (let i = 0; i < hub.length; i++) {

                let distance = getDistance(point, hub[i]);

                let opacity = 1 - distance / opt.minDistance;

                if (opacity > 0) {

                    ctx.lineWidth = 0.5;

                    ctx.strokeStyle = "rgba(" + line[0] + "," + line[1] + "," + line[2] + "," + opacity + ")";

                    ctx.beginPath();

                    ctx.moveTo(point.x, point.y);

                    ctx.lineTo(hub[i].x, hub[i].y);

                    ctx.closePath();

                    ctx.stroke();

                }

            }

        }



        function getDistance(point1, point2) {

            return Math.sqrt(Math.pow(point1.x - point2.x, 2) + Math.pow(point1.y - point2.y, 2));

        }



        function getSize() {

            w = canvas.width = window.innerWidth;

            h = canvas.height = window.innerHeight;

        }

        function Partical() {

            this.x = Math.random() * w;

            //粒子的x轴坐标

            this.y = Math.random() * h;

            //粒子的y轴坐标

            this.speed = opt.defaultSpeed + opt.variantSpeed * Math.random();

            //粒子的运动速度

            this.directionAngle = Math.floor(Math.random() * 360);

            //粒子运动的方向

            this.color = opt.particleColor;

            //粒子的颜色

            this.radius = opt.defaultRadius + Math.random() * opt.variantRadius;

            //粒子的半径大小

            this.vector = {



                x: this.speed * Math.cos(this.directionAngle),

                //粒子在x轴的速度

                y: this.speed * Math.sin(this.directionAngle)

                //粒子在y轴的速度

            }

            this.update = function () {

                //粒子的更新函数

                this.border();

                //判断粒子是否到了边界

                this.x += this.vector.x;

                //粒子下一时刻在x轴的坐标

                this.y += this.vector.y;

                //粒子下一时刻在y轴的坐标

            }

            this.border = function () {

                //判断粒子是都到达边界

                if (this.x >= w || this.x <= 0) {

                    //如果到达左右边界，就让x轴的速度变为原来的负数

                    this.vector.x *= -1;

                }

                if (this.y >= h || this.y <= 0) {

                    //如果到达上下边界，就让y轴的速度变为原来的负数

                    this.vector.y *= -1;

                }

                if (this.x > w) {

                    //下面是改变浏览器窗口大小时的操作，改变窗口大小后有的粒子会被隐藏，让他显示出来即可

                    this.x = w;

                }

                if (this.y > h) {

                    this.y = h;

                }

                if (this.x < 0) {

                    this.x = 0;

                }

                if (this.y < 0) {

                    this.y = 0;

                }

            }

            this.draw = function () { //绘制粒子的函数

                ctx.beginPath();

                ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);

                ctx.closePath();

                ctx.fillStyle = this.color;

                ctx.fill();

            }

        }
    </script>

</body>

</html>